既存の大量の Lambda 関数に、Errors と Throttles メトリクスのアラーム通知設定を自動で行う
はじめに
こんにちは、サービスグロースチームの筧です。
「既存の大量の Lambda 関数に対して、CloudWatchLogs の Error や Throttles のメトリクスのログを取得して Slack に通知する設定をしたい」
って思ったことありませんか? 通知設定方法の一つとしては、Lambda 関数を CloudWatch アラームでモニタリングし、Amazon SNS 経由で AWS Chatbot で通知する方法があります。
Lambda 関数を 、AWS Chatbot で通知を受け取る | Amazon Web Services ブログ
上記ブログののソリューションでは、モニタリングしたい Lambda 関数を指定したい際に、 CloudFormation のパラメータに、Lambda 関数名をカンマ区切りリストで入力しています。 こちらのソリューションの利用を検討した際に、モニタリングしたい Lambda 関数をパラメータ入力ではなく、 自動的に追加されるような機能があれば、更に簡単に展開でき、メンテナンスも減って良いなと思いました。
つくったもの
そこで以下の PoC サービスを作成しました。
- Serverless Framework の resources で、緑枠のリソースを作成。当該内容は先日のブログで紹介済です。
- Amazon SNS Topic
- AWS Chatbot SlackChannelConfiguration
- IAM Role(上記 AWS Chatbot 設定用の IAM Role)
Serverless Framework で AWS Chatbot と Amazon SNS のリソースを作成してみた
- Serverless Framework の functionsで、赤枠のリソースを追加/削除する機能を持つ Lambda 関数を作成。Lambda 関数は Step Functions のステートマシンの Task として定義されており、Amazon EventBridge のイベントルールで日本時間正午にそのステートマシンが実行されるようにイベントスケジュール。本ブログではこちらの Serverless Framework の functions を作成する箇所をメインにご紹介します。
前提
筆者の環境
% sw_vers ProductName: macOS ProductVersion: 12.2.1 BuildVersion: 21D62 % sls --version Framework Core: 3.19.0 (local) 3.19.0 (global) Plugin: 6.2.2 SDK: 4.3.2 % pipenv --version pipenv, version 2022.6.7
リポジトリ
- コードは以下です。
- Issues には今後実装したい機能や既知の問題を記載しています。
動かしてみる
セットアップ
以下の README を参照してセットアップください。
Code - takaakikakei/blog-alert-lambda | GitHub
README にも書いていますが、アラーム設定したいリージョンごとにセットアップが必要です。 システムの仕様上、東京リージョン(ap-northeast-1)アラーム設定したい Lambda 関数がない場合でも必ずセットアップしてください。 セットアップ後、セットアップ済みのリージョンで、アラーム設定されてない Lambda 関数はイベントスケジュールに従って自動追加されます。
本ブログでは東京リージョン(ap-northeast-1)のみでセットアップした前提で進めます。
Add function の実行
Add functionは、CloudWatch アラームの追加に利用します。東京リージョンの CloudWatch アラームのサービス画面にアクセスしてみると、現在の環境では、アラームが既に17個設定されている状況です。
Lambda のサービス画面にアクセスしてみると、108個の関数が存在していることが分かります。手動で全ての関数に CloudWatch アラームを設定するのは大変です。
Add function に紐づくステートマシンを手動実行します。
成功したら、CloudWatch アラームのサービス画面に再度アクセスしてみます。233個のアラームが設定されており、216個(108 * 2) のアラームが追加されたことが分かります。なぜ Lambda 関数の2倍のアラームが設定されたかというと、Errors と Throttles のメトリクスごとにアラームを作成しているからです。これで大量のアラームを簡単に設定できました。
なお、ステートマシンの設定上で、Amazon EventBridge のイベントルールを定義しており、日本時間正午にステートマシンが実行されるように、イベントスケジュールしています。なので適当な Lambda 関数を追加して、次の日本時間正午時間まで待つと、自動で対象関数用のアラームも追加されます。
エラー通知を確認する
serverless.yml の functions で create_error を定義しています。これは 意図的にエラーを発生させる Lambda 関数です。対象の Lambda 関数のサービス画面にアクセスして、テスト実行します。
数分で Slack 通知がされました。
通知がこない場合、CloudWatch アラームの設定が裏側で時間がかかっている可能性があります。時間をあけてリトライしてみてください。Slack 通知内容の Show logs や Show error logs をクリックすることで、Slack 上で、CloudWatch Logs の内容も確認できます。便利ですよね。
Delete function の実行
Delete functionは、設定した CloudWatch アラームの一括削除に利用します。 Delete function に紐づくステートマシンを手動実行します。
成功したら、CloudWatch アラームのサービス画面に再度アクセスしてみます。本ツールで作成したアラームが全て削除され、アラームが17個に戻っていることが分かります。
function の概要説明
Add function(CloudWatch アラームの追加関数)
概要
Add function はデプロイ済みの Lambda 関数に、CloudWatch アラームを自動設定する関数になります。デプロイ済みの Lambda 関数と、本ツールでアラーム設定した Lambda 関数の diff を取り、アラーム未設定の Lambda 関数にアラーム設定を行います。CloudWatch アラームの設定内容としては、Lambda 関数の CloudWatchLogs で Errors と Throttles のログが出力された際に、前回のブログで設定した、Amazon SNS と AWS Chatbot を経由して、Slack へアラーム通知を行います。
コードの定義箇所
serverless.yml では functions で add として定義しています。そして、includes/state-machines.yml のステートマシンの設定上で、add を参照しています。またステートマシンの設定上で、Amazon EventBridge のイベントルールを定義しており、日本時間正午にステートマシンが実行されるように、イベントスケジュールしています。もちろん、対象のステートマシンで手動実行も可能です。
・・snip・・ functions: add: handler: src/handlers/add.handler timeout: 300 delete: handler: src/handlers/delete.handler timeout: 300 create_error: handler: src/handlers/create_error.handler timeout: 60 ・・snip・・ stepFunctions: ${file(includes/state-machines.yml)} ・・snip・・
stateMachines: AlertLambda-Add: events: - schedule: cron(00 03 * * ? *) #https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/services-cloudwatchevents-expressions.html name: AlertLambda-Add-${self:provider.stage} definition: StartAt: Add States: Add: Type: Task InputPath: "$" Resource: Fn::GetAtt: [add, Arn] ResultPath: "$" End: true
Lambda関数自体は src 配下に書いています。階層構造を定義していますが、それぞれの役割は以下です。 handlers -> use_cases -> services 配下の関数順に確認すると分かりやすいと思います。
- handlers: function のエントリーポイントを定義
- add.py
- use_cases: function のビジネスロジックを定義
- add.py
- services: function で用いるサービスを定義
- cloudwatch.py
- lambda_client.py
Delete function(CloudWatch アラームの削除関数)
概要
Delete function は本ツールで設定した CloudWatch アラームを一括削除する関数になります。CloudWatch アラーム名の prefix が AlertLambda のものを削除します。万が一、本ツール設定以前に当該 prefix を利用した CloudWatch アラームがある場合は、誤削除に注意ください。
コードの定義箇所
serverless.yml では functions で delete として定義しています。そして、includes/state-machines.yml のステートマシンの設定上で、delete を参照しています。対象のステートマシンで手動実行も可能です。
・・snip・・ functions: add: handler: src/handlers/add.handler timeout: 300 delete: handler: src/handlers/delete.handler timeout: 300 create_error: handler: src/handlers/create_error.handler timeout: 60 ・・snip・・ stepFunctions: ${file(includes/state-machines.yml)} ・・snip・・
・・snip・・ AlertLambda-Delete: name: AlertLambda-Delete-${self:provider.stage} definition: StartAt: Delete States: Delete: Type: Task InputPath: "$" Resource: Fn::GetAtt: [delete, Arn] ResultPath: "$" End: true
Add function と同じく、Lambda関数自体は src 配下に書いており、同じ階層構造を取っています。
- handlers: function のエントリーポイントを定義
- delete.py
- use_cases: function のビジネスロジックを定義
- delete.py
- services: function で用いるサービスを定義
- cloudwatch.py
おわりに
最後まで読んでいただきありがとうございます。 ご紹介したツールを活用することで、皆さんのシステム監視の負荷が軽減できたら幸いです。
それではまた!